R es un lenguaje de programación y un entorno de software diseñado específicamente para estadísticas y análisis de datos. Desarrollado por estadísticos y científicos computacionales, R proporciona herramientas robustas para manipular, visualizar y modelar datos, convirtiéndolo en una opción popular entre profesionales en campos como la ciencia de datos, la investigación académica y la analítica empresarial. Su naturaleza de código abierto y la amplia gama de paquetes y extensiones disponibles permiten a los usuarios personalizar y ampliar sus capacidades según sus necesidades específicas. R se destaca por su flexibilidad y potencia en la exploración y comprensión de datos, convirtiéndolo en una herramienta valiosa en el mundo del análisis estadístico.
La importación de datos es un proceso crucial en cualquier análisis de datos, ya que la calidad y la precisión de los resultados dependen en gran medida de la calidad de los datos de entrada. La importancia de importar datos desde distintas fuentes radica en la diversidad y complejidad de la información que puede ser crucial para la toma de decisiones informadas
# Especificar la ruta del archivo Excel
ruta_archivo <- "01_Informacion_Data/Bureau_Labor_of_Statistics_Data/Detroit_Warren_Dearborn.xlsx"# Cargar la biblioteca openxlsx para trabajar con archivos Excel
library(openxlsx)
# Leer datos desde la primera hoja del archivo Excel
Employment_1 <- read.xlsx(ruta_archivo, sheet = 1)
# Imprimir los datos cargados para verificar la lectura correcta del archivo
Employment_1Es frecuente toparse con archivos Excel que presentan encabezados o filas vacías previas a los datos reales. Tanto las bibliotecas readxl como openxlsx brindan una solución sencilla para abordar esta situación.
Aquí tienes un ejemplo utilizando la biblioteca readxl:
# install.packages("readxl")
library(readxl)
# Leer el archivo Excel, omitiendo 10 filas al principio
Employment <- read_excel(
path = ruta_archivo,
sheet = "BLS Data Series",
skip = 10
)
EmploymentEste código ejemplifica cómo cargar un archivo Excel, específicamente desde la hoja “BLS Data Series”, omitiendo las primeras 10 filas que contienen encabezados o información no deseada.
# Especificar la ruta del archivo CSV
file_ruta <- "01_Informacion_Data/Zillow/Zip_zhvi_uc_sfrcondo_tier_0.33_0.67_sm_sa_month.csv"
# Leer el archivo Excel
Zillow <- read.csv(file = file_ruta)
head(Zillow)En el ámbito del análisis de datos, la eficiencia y la consistencia en la manipulación de conjuntos de datos son fundamentales. En este contexto, el presente documento explora un script en R diseñado para automatizar la extracción, manipulación y limpieza de datos.
El script aborda la gestión de archivos ZIP que contienen información demográfica clave, extraída de diversas fuentes. A través de una serie de pasos, el código facilita la obtención, procesamiento y consolidación de datos en un formato más manejable y analítico.
El análisis se inicia con la configuración del directorio de trabajo y la identificación de archivos ZIP relevantes. A continuación, se descomprimen estos archivos para revelar conjuntos de datos en formato CSV. Estos datos son entonces leídos, manipulados y agregados en un marco de datos unificado. Además, se realiza una limpieza de archivos temporales para mantener la integridad del espacio de trabajo.
El objetivo de este script es proporcionar una herramienta eficaz para investigadores, analistas y profesionales de datos que deseen analizar y comprender las tendencias demográficas a lo largo del tiempo.
A lo largo del documento, se detallarán cada una de las secciones del código, explicando las decisiones de diseño y brindando orientación sobre cómo adaptar el script a diferentes contextos y conjuntos de datos.
Acompáñenos en este recorrido a través de un proceso automatizado que simplifica la gestión y análisis de datos demográficos del United States Census Bureau en el entorno de programación R.
¡Comencemos!
# Cargar la biblioteca
library(purrr)
library(tidyverse)
library(readr)
# Configuración del directorio y archivos ZIP
my_dir <- "01_Informacion_Data/US_Census_Bureau/"
zip_files <- list.files(path = my_dir, pattern = "*.zip", full.names = TRUE)
# Descomprimir archivos ZIP
unzip_files <- map(zip_files, ~unzip(.x, exdir = my_dir))En esta sección, se configura el directorio de trabajo y se identifican los archivos ZIP en el directorio. Luego, se descomprimen los archivos ZIP en la misma ubicación.
## [1] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2011.DP05-Column-Metadata.csv"
## [2] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2011.DP05-Data.csv"
## [3] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2011.DP05-Table-Notes.txt"
## [4] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2011.DP05_2022-10-31T180229.zip"
## [5] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2012.DP05-Column-Metadata.csv"
## [6] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2012.DP05-Data.csv"
## [7] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2012.DP05-Table-Notes.txt"
## [8] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2012.DP05_2022-11-01T080453.zip"
## [9] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2013.DP05-Column-Metadata.csv"
## [10] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2013.DP05-Data.csv"
## [11] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2013.DP05-Table-Notes.txt"
## [12] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2013.DP05_2022-11-01T081112.zip"
## [13] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2014.DP05-Column-Metadata.csv"
## [14] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2014.DP05-Data.csv"
## [15] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2014.DP05-Table-Notes.txt"
## [16] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2014.DP05_2022-11-01T081604.zip"
## [17] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2015.DP05-Column-Metadata.csv"
## [18] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2015.DP05-Data.csv"
## [19] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2015.DP05-Table-Notes.txt"
## [20] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2015.DP05_2022-11-01T081827.zip"
## [21] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2016.DP05-Column-Metadata.csv"
## [22] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2016.DP05-Data.csv"
## [23] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2016.DP05-Table-Notes.txt"
## [24] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2016.DP05_2022-11-01T082249.zip"
## [25] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2017.DP05-Column-Metadata.csv"
## [26] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2017.DP05-Data.csv"
## [27] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2017.DP05-Table-Notes.txt"
## [28] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2017.DP05_2022-11-01T082643.zip"
## [29] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2018.DP05-Column-Metadata.csv"
## [30] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2018.DP05-Data.csv"
## [31] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2018.DP05-Table-Notes.txt"
## [32] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2018.DP05_2022-11-01T082752.zip"
## [33] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2019.DP05-Column-Metadata.csv"
## [34] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2019.DP05-Data.csv"
## [35] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2019.DP05-Table-Notes.txt"
## [36] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2019.DP05_2022-11-01T083027.zip"
## [37] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2020.DP05-Column-Metadata.csv"
## [38] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2020.DP05-Data.csv"
## [39] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2020.DP05-Table-Notes.txt"
## [40] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2020.DP05_2022-11-01T083111.zip"
## [41] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2021.DP05-Column-Metadata.csv"
## [42] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2021.DP05-Data.csv"
## [43] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2021.DP05-Table-Notes.txt"
## [44] "01_Informacion_Data/US_Census_Bureau/ACSDP5Y2021.DP05_2023-09-12T103937.zip"
## [45] "01_Informacion_Data/US_Census_Bureau/pop_data.rds"
## [46] "01_Informacion_Data/US_Census_Bureau/pop_data.xlsx"
# Obtener archivos de datos en formato CSV
data_files <- list.files(path = my_dir, pattern = "*Data.csv", full.names = TRUE)
# Leer archivos CSV y almacenar en una lista
pop_data <- map(.x = data_files, .f = read.csv, skip = 1, header = TRUE)
# Agregar la columna 'Year' a cada conjunto de datos
for (i in 1:length(pop_data)) {
pop_data[[i]]$Year <- 2010 + i
}
# Combinar la lista de conjuntos de datos en un marco de datos
pop_data <- map_dfr(.x = pop_data, .f = pluck)
# Seleccionar columnas relevantes
pop_data <- pop_data %>%
select(
Geographic.Area.Name,
Estimate..SEX.AND.AGE..Total.population,
Year
)En esta sección, se identifican los archivos CSV que contienen “Data” en su nombre. Estos archivos se leen y manipulan para agregar una columna ‘Year’ a cada conjunto de datos. Luego, se combinan en un único marco de datos y se seleccionan las columnas relevantes.
# Obtener la lista de archivos .csv y .txt en el directorio
files_to_remove <- list.files(path = my_dir, pattern = "\\.(csv|txt)$", full.names = TRUE)
# Verificar si hay archivos para eliminar
if (length(files_to_remove) > 0) {
# Eliminar los archivos
file.remove(files_to_remove)
cat("Archivos .csv y .txt eliminados correctamente en el directorio:", my_dir)
} else {
cat("No hay archivos .csv y .txt para eliminar en el directorio:", my_dir)
}## Archivos .csv y .txt eliminados correctamente en el directorio: 01_Informacion_Data/US_Census_Bureau/
Finalmente, se identifican los archivos temporales (CSV y TXT) y se eliminan. Se proporciona un mensaje indicando si se eliminaron archivos o si no se encontraron archivos para eliminar.
Este código en R se desarrolló con el propósito de importar datos mediante una interfaz de programación de aplicaciones (API) para obtener información relacionada con códigos postales en los Estados Unidos.
# Configurar la URL y claves de la API
url <- "https://us-zip-code-to-income.p.rapidapi.com/"
API_Key <- "f7eec58e6cmsh805b1f341c11ff4p18a6b6jsn441ba456adeb" #uwu xd#
API_Host <- "us-zip-code-to-income.p.rapidapi.com"
request_delay <- 2 # Definir el retardo entre las solicitudes (en segundos)En la sección inicial del código, se establecen las variables esenciales para la configuración de la API. Esto incluye la URL de la API, la clave de autenticación (API_Key), el host de la API (API_Host), y un retardo entre las solicitudes (request_delay) para cumplir con los límites de la API y evitar posibles restricciones.
# missing_zip_codescrime_zip que se quiere extraer de la API
missing_zip_codescrime_zip <- c("48430", "48211", "48760", "48139", "48440")# Cargar la biblioteca
library(httr)
library(jsonlite)
library(tidyverse)
library(fs)
library(rvest)
library(xml2)
library(readxl)
library(dplyr)
# Definir una función para importar datos utilizando la API
data_import_IP <- function(url, API_Key, API_Host, request_delay) {
data_df <- tibble()
for (i in seq_along(missing_zip_codescrime_zip)) {
query_params <- list(zip = missing_zip_codescrime_zip[i])
# Realizar la solicitud GET a la API
response <- GET(url, add_headers("X-RapidAPI-Key" = API_Key, "X-RapidAPI-Host" = API_Host), query = query_params)
# Verificar el estado de la respuesta
stop_for_status(response)
# Convertir la respuesta JSON a un marco de datos
cont_response <- fromJSON(rawToChar(response$content))
# Concatenar el marco de datos resultante
data_df <- bind_rows(data_df, as_tibble(cont_response))
# Imprimir información sobre el código postal procesado
print(str_glue("Zip Code: {missing_zip_codescrime_zip[i]}"))
# Retardo entre las solicitudes para evitar límites de la API
Sys.sleep(request_delay)
}
# Nombrar las columnas del marco de datos resultante
colnames(data_df) <- c("success", "zip", "House Hold Median Income", "household MeanIncome", "familyMedianIncome", "familyMeanIncome", "numHouseholds", "nonFamilyHousehold MedianIncome", "nonFamilyHouseholdMeanIncome", "familyPercentPoverty")
return(data_df)
}La función ‘data_import_IP’ tiene como objetivo principal realizar solicitudes a una API para obtener información relacionada con códigos postales en los Estados Unidos. Aquí está una explicación paso a paso de lo que hace la función:
1.Inicialización del Marco de Datos:
2.Bucle de Importación de Datos:
3.Construcción de Parámetros de Consulta:
4.Solicitud GET a la API:
5.Procesamiento de la Respuesta JSON:
6.Concatenación de Resultados:
7.Impresión de Información del Código Postal:
8.Retardo entre Solicitudes:
Para cumplir con las políticas de velocidad de la API y evitar exceder límites, se introduce un retardo de tiempo (‘Sys.sleep(request_delay)’) entre cada solicitud.
9.Nombrar Columnas del Marco de Datos Resultante:
10.Retorno del Resultado:
# Llamar a la función de importación de datos utilizando la API
result_df <- data_import_IP(url, API_Key, API_Host, request_delay)## Zip Code: 48430
## Zip Code: 48211
## Zip Code: 48760
## Zip Code: 48139
## Zip Code: 48440
En R, puedes crear tus propias funciones y guardarlas en un script separado para luego poder utilizarlas en otros scripts. Aquí hay un ejemplo paso a paso:
1.Crea tu función en un script: * Abre un nuevo script en R (puedes usar un editor de texto o un entorno de desarrollo como RStudio). Define tu función y guárdala en el script. Por ejemplo, crea un archivo llamado misFunciones.R con el siguiente contenido:
2.Guarda el script: * Guarda el script con el nombre que hayas elegido, en este caso, ‘misFunciones.R’.
3.Usa la función en otro script: * En otro script o en la consola de R, puedes cargar el script que contiene tus funciones usando la función ‘source’. Aquí hay un ejemplo:
# scriptPrincipal.R
# Cargar el script que contiene las funciones
> source("misFunciones.R")
# Ahora puedes utilizar la función en este script
> resultado_suma <- sumaDosNumeros(3, 5)
> print(resultado_suma)
En estas líneas de código se utilizan para almacenar el objeto ‘pop_data’ en un archivo RDS y luego cargarlo de nuevo en el entorno de trabajo de R en el objeto ‘pop_data’. Este proceso es útil para persistir datos entre sesiones de trabajo o compartir datos de manera eficiente, ya que el formato RDS conserva la estructura y los tipos de datos del objeto original.
# Definir valores de prueba para DWD_MI_Zip y crime_zip
DWD_MI_Zip <- c("10001", "20002", "30303", "40004", "50005")
crime_zip <- c("10001", "30303", "50005", "60006", "70007")
# Comprobar si los conjuntos de códigos postales son idénticos
identical_result <- identical(DWD_MI_Zip, crime_zip)
print(paste("Los conjuntos son idénticos:", identical_result))## [1] "Los conjuntos son idénticos: FALSE"
La función identical() se utiliza para verificar si dos objetos son idénticos entre sí. La función devuelve un valor lógico (TRUE o FALSE) según si los objetos son idénticos o no.
# Mostrar los códigos postales que faltan en cada conjunto
missing_DWD_MI_Zip <- DWD_MI_Zip[!DWD_MI_Zip %in% crime_zip]
missing_crime_zip <- crime_zip[!crime_zip %in% DWD_MI_Zip]
print("Códigos postales que faltan en DWD_MI_Zip:")## [1] "Códigos postales que faltan en DWD_MI_Zip:"
## [1] "20002" "40004"
## [1] "Códigos postales que faltan en crime_zip:"
## [1] "60006" "70007"
Este código en R tiene como objetivo identificar y mostrar los códigos postales que faltan en dos conjuntos de datos, DWD_MI_Zip y crime_zip. Utiliza la función %in% para realizar la comparación entre los dos conjuntos y determinar los elementos que no están presentes en ambos.
La librería scales en R proporciona funciones para transformar y formatear datos, especialmente útiles para la visualización de gráficos. Aquí hay un resumen de las principales funciones y utilidades proporcionadas por scales:
# Cargar la biblioteca
library(scales)
# Numero de prueba
number <- 5.1234567
# Formato de dolares
number |>
scales::dollar()## [1] "$5.12"
## [1] "512.35%"
# Crear un vector de fechas
dates <- as.Date(c("2022-01-15 12:30:00", "2022-02-20 15:45:00", "2022-03-25 18:15:00"))
# Formatear las fechas en el estilo "día de la semana, mes día, año"
formatted_dates <- date_format("%A, %B %d, %Y")(dates)
print(formatted_dates)## [1] "sábado, Enero 15, 2022" "domingo, Febrero 20, 2022"
## [3] "viernes, Marzo 25, 2022"
# Crear un vector de horas
times <- as.POSIXct(c("2022-01-15 12:30:00", "2022-02-20 15:45:00", "2022-03-25 18:15:00"))
# Formatear las horas en el estilo "hora:minuto AM/PM"
formatted_times <- time_format("%I:%M %p")(times)
print(formatted_times)## [1] "05:30 p. m." "08:45 p. m." "11:15 p. m."
# Crear un vector de fechas y horas
datetime <- as.POSIXct(c("2022-01-15 12:30:00", "2022-02-20 15:45:00", "2022-03-25 18:15:00"))
# Formatear las fechas y horas en el estilo "día de la semana, mes día, año hora:minuto AM/PM"
formatted_datetime <- date_format("%A, %B %d, %Y %I:%M %p")(datetime)
print(formatted_datetime)## [1] "sábado, Enero 15, 2022 05:30 p. m."
## [2] "domingo, Febrero 20, 2022 08:45 p. m."
## [3] "viernes, Marzo 25, 2022 11:15 p. m."
En R, la función ‘filter’ se utiliza comúnmente para extraer filas específicas de un conjunto de datos basándose en condiciones específicas. Aquí tienes algunos ejemplos de cómo usar la función ‘filter’:
library(dplyr)
# Crear un ejemplo de dataframe
df <- data.frame(
ID = c(1, 2, 3, 4, 5, 6),
Name = c("Alice", "Bob", "Charlie", "David", "Eva", "Fernanda"),
Age = c(25, 30, 22, 35, 28, NaN),
Gender = c("Female", "Male", "Male", "Male", "Female", "Female")
)
df# Filtrar personas mayores de 25 años y de género femenino
result <- filter(df, Age > 25 & Gender == "Female")
resultlibrary(naniar)
# Resumen de valores faltantes en el conjunto de datos filtrado
miss_val_resumen <- df |>
miss_case_summary()
# Imprimir el resumen
miss_val_resumenLa función mutate() es parte del paquete dplyr en R y se utiliza para realizar transformaciones en columnas existentes o agregar nuevas columnas a un conjunto de datos. Esta función es comúnmente utilizada en el contexto de manipulación y transformación de datos.
# Instala e carga las librerías necesarias si no las has instalado
library(dplyr)
library(lubridate)
# Crear un conjunto de datos ficticio con una columna de fechas
datos <- data.frame(
Date_chr = c("2022-01-15", "2021-08-22", "2023-03-10")
)
# Utilizar mutate() y year() para crear una nueva columna "Year"
datos_con_year <- datos %>%
mutate(Year = year(ymd(Date_chr)))
# Imprimir el conjunto de datos resultante
datos_con_year# Crear ejemplo de df1
df1 <- data.frame(
ID = c(1, 2, 3, 4, 2, 3, 4),
Nombre = c("Alice", "Bob", "Charlie", "David","Bob", "Charlie", "David"),
Apellido = c("Smith", "Johnson", "Garcia", "Fisher","Johnson", "Garcia", "Fisher")
)
# Crear ejemplo de df2
df2 <- data.frame(
ID = c(2, 3, 4, 5, 3, 4, 2),
Ventas = c(2250, 5047, 5461, 7539, 2250, 5047, 5461)
)# Ejemplo de agrupación y resumen
ventas_resumen <- merged_df %>%
group_by(Nombre) %>%
summarise(Total_Ventas = sum(Ventas))
ventas_resumen# Ejemplo de combinación de columnas
merged_df <- merged_df %>%
mutate(Nueva_Columna = paste(Nombre, Apellido, sep = "-"))
merged_dfLos gráficos desempeñan un papel fundamental en el análisis de datos y la visualización de resultados en el ámbito de la programación estadística, y R se destaca como un lenguaje de programación especialmente poderoso para la creación de gráficos.
# Cargar bibliotecas necesarias
library(readxl)
library(tidyverse)
library(naniar)
library(lubridate)
library(stringr)
library(fs)
library(scales)
library(ggplot2)
library(plotly)
library(tidyquant)
library(ggrepel)
# Fuente de las funciones personalizadas
source("06_funciones_y_interacion_iteration/Zillow_PC_Function.R")
source("06_funciones_y_interacion_iteration/funciones_de_importacion.R")
# Obtener datos de ciudades con la Tasa de Crecimiento Anual Compuesta (CAGR) para los años 2000 a 2022
CAGR_Data <- getTopCitiesByCAGR(2000, 2022, 30)
# Importar datos del Índice del Mercado Inmobiliario de Zillow (ZMI)
ZMI_Data_Prep <- data_import("ZMI_data_pre")
# Combinar los marcos de datos CAGR_Data y ZMI_Data_Prep en la columna "City_zip"
ZillowTrends <- CAGR_Data |> left_join(ZMI_Data_Prep, by = "City_zip")
ZillowTrendsUtilizando la función ‘gg_miss_var’ de la biblioteca ‘naniar’ para visualizar los valores perdidos en los datos.
# Seleccionar las columnas relevantes en el marco de datos ZillowTrends
ZillowTrends <- ZillowTrends |>
select(City_zip, Year, Z_Home_Value_Index, ZHVI_PC_YoY, ZHVI_PC_YoY_chr, timeperiod, Number_of_Years, CAGR)
# Calcular la tasa de crecimiento promedio (CAGR) para todos los datos
ave_rate <- ZillowTrends |>
pull(CAGR) |>
mean() |>
scales::percent(accuracy = 0.01)
# Obtener el año mínimo y máximo en el conjunto de datos ZillowTrends
min_y <- ZillowTrends |>
pull(Year) |>
min()
max_y <- ZillowTrends |>
pull(Year) |>
max()
# Agregar una nueva columna 'tool_tip' con información para etiquetas emergentes
ZillowTrends <- ZillowTrends |>
mutate(tool_tip = str_glue("CityZip: {City_zip},
%Change: {ZHVI_PC_YoY_chr},
Year: {Year}"))
# Crear un gráfico ggplot
g <- ZillowTrends |> ggplot(aes(x = Year, y = ZHVI_PC_YoY, color = City_zip, text = tool_tip, group = City_zip)) +
geom_line(linewidth = 1) +
geom_point(size = 2, alpha = 0.5) +
geom_hline(yintercept = 0, linetype = "dashed", color = "black", linewidth = 0.50) +
labs(
title = "Apreciación de Precios de Viviendas Año tras Año",
subtitle = str_glue("Cambio porcentual YoY de {min_y} a {max_y}"),
x = "AÑO",
y = "Cambio Porcentual (%)",
caption = str_glue("De {min_y} a {max_y}, la CAGR promedio ha sido {ave_rate} \n para estos 30 principales códigos postales en el Área Metropolitana de Detroit")
)
# Mostrar el gráfico
g##Convierte el gráfico a un gráfico interactivo
Convierte el gráfico creado con ggplot2 a un gráfico interactivo utilizando plotly y especifica que las etiquetas de herramientas deben tomarse de la columna ‘tool_tip’.
# Crear un gráfico ggplot con facetas (Plot 2)
g <- ZillowTrends |> ggplot(aes(x = Year, y = ZHVI_PC_YoY, color = City_zip, text = tool_tip, group = City_zip)) +
geom_line(linewidth = 1) + # Agregar líneas para representar los datos
geom_point(size = 2, alpha = 0.5) + # Agregar puntos para representar los datos
geom_hline(yintercept = 0, linetype = "dashed", color = "black", linewidth = 0.50) + # Agregar línea horizontal en y=0
facet_wrap(~ City_zip, scales = "free_y") + # Facetar el gráfico por código postal con escalas independientes en el eje y
labs(
title = "Apreciación de Precios de Viviendas Año tras Año",
subtitle = str_glue("Cambio porcentual YoY de {min_y} a {max_y}"),
x = "AÑO",
y = "Cambio Porcentual (%)",
caption = str_glue("De {min_y} a {max_y}, la CAGR promedio ha sido {ave_rate} \n para estos 30 principales códigos postales en el Área Metropolitana de Detroit")
) +
theme_minimal() + # Puedes ajustar el tema según tus preferencias
theme(
plot.title = element_text(size = 20, face = "bold"),
axis.title.x = element_text(size = 16),
axis.title.y = element_text(size = 16),
axis.text.x = element_text(size = 6),
axis.text.y = element_text(size = 6),
legend.text = element_text(size = 12)
) +
guides(color = guide_legend(override.aes = list(size = 4))) # Ajustar el tamaño de la leyenda
g# Convertir el gráfico ggplot a una versión interactiva usando plotly
g_plotly <- g |> ggplotly(tooltip = "tool_tip")
# Ajustar el tamaño del gráfico plotly
g_plotly <- g_plotly %>%
config(displayModeBar = TRUE) %>% # Puedes desactivar la barra de herramientas si lo prefieres
layout(width = 1000, height = 600) # Ajustar el tamaño según tus preferencias
# Mostrar el gráfico plotly
g_plotlyEmployment_C <- data_import("Employment_C")
# Calcular el promedio del cambio porcentual YoY del índice de valor de la vivienda (ZHVI_PC_YoY) por año
avg_zhvi_pc_by_year <- ZMI_Data_Prep |>
group_by(Year) |>
summarise("Home Value Index" = ZHVI_PC_YoY |> mean())
# Combinar datos de empleo y datos del índice de valor de la vivienda por año
homev_vs_Job_growth <- Employment_C |>
left_join(avg_zhvi_pc_by_year, by = "Year") |>
select(Year, PC_YoY, "Home Value Index") |>
mutate("Employment in Metro Detroit" = PC_YoY) |>
gather(key = "Legend", value = "Percentage_Change", "Employment in Metro Detroit", "Home Value Index")
# Modificar el formato de porcentaje y la etiqueta del texto
homev_vs_Job_growth <- homev_vs_Job_growth |>
mutate(PC_YoY_chr = Percentage_Change |> scales::percent(accuracy = 0.01)) |>
mutate(Percentage_Change = (Percentage_Change * 100)) |>
mutate(label_text = str_glue("Legend:{Legend},
Year:{Year},
Percentage:{PC_YoY_chr}"))
# Calcular el número de códigos postales únicos en ZMI_Data_Prep
num_of_zip <- ZMI_Data_Prep |> select(City_zip) |> unique() |> nrow()
# Crear el gráfico ggplot para el Plot 3
p3 <- homev_vs_Job_growth |>
drop_na(Percentage_Change) |>
ggplot(aes(x = Year, y = Percentage_Change, linetype = Legend, colour = Legend, label = label_text)) +
geom_line(linewidth = 1) +
geom_point(aes(text = label_text), size = 2) +
geom_hline(yintercept = 0, linetype = "dashed", color = "gray0", size = 0.50)+
labs(
title = "Precios de Viviendas vs Empleo",
subtitle = "Cambio Porcentual YoY entre Precios de Viviendas y Empleo",
y = "Cambio Porcentual (%)",
caption = str_glue("Las fuentes de datos son 'Zillow' y 'Bureau of Labor Statistics'.
Los datos de empleo son del área de Empleo de Detroit-Warren-Dearborn.
El Índice de Valor de la Vivienda es la media del cambio de {num_of_zip} códigos postales en el área de Detroit-Warren-Dearborn.'"
)) +
theme_light()
# Convertir el gráfico ggplot a una versión interactiva usando plotly
p3_plotly <- p3 |> ggplotly(tooltip = "text")
# Mostrar el gráfico plotly
p3_plotlyp3 + theme (
plot.title = element_text(color="dark blue", size = 12, face = "bold"),
plot.subtitle = element_text(color="dark blue", size = 10, face = "italic"),
plot.caption = element_text(color="dark blue", size = 8, face = "bold.italic")
) ## (LOESS) Local Polynomial Regression
# Combinar datos de empleo y datos del índice de valor de la vivienda por año
homev_vs_Job_growth_II <- Employment_C |>
left_join(avg_zhvi_pc_by_year, by = "Year") |>
select(Year, PC_YoY, "Home Value Index") |>
mutate(Employment = PC_YoY) |>
mutate(Home_Value_Index = `Home Value Index`) |>
filter(Year > 1999)
# Ajustar un modelo LOESS (Local Polynomial Regression)
mod <- loess(Home_Value_Index ~ Employment, data = homev_vs_Job_growth_II)
grid <- tibble(Employment = seq(min(homev_vs_Job_growth_II$Employment), max(homev_vs_Job_growth_II$Employment), length = 50))
grid$Home_Value_Index <- predict(mod, newdata = grid)
# Calcular residuos estandarizados y identificar valores atípicos
std_resid <- resid(mod) / mod$s
outlier <- filter(homev_vs_Job_growth_II, abs(std_resid) > 1)
outlier# Crear un gráfico ggplot para el modelo LOESS
p4 <- ggplot(homev_vs_Job_growth_II, aes(Employment, Home_Value_Index)) +
geom_point() +
geom_line(data = grid, colour = "blue", size = 1.5) +
ggrepel::geom_text_repel(data = outlier, aes(label = Year)) +
labs(
title = "Regresión LOESS",
y = "Cambio Promedio % Índice de Valor de la Vivienda",
x = "Cambio Promedio % Empleo",
caption = "La regresión LOESS, a veces llamada regresión local, es un método que utiliza el ajuste local para ajustar un modelo de regresión a un conjunto de datos"
)
# Añadir anotaciones al gráfico
p4 + annotate(geom = "curve",
x = -0.10,
y = 0.09,
xend = -0.106,
yend = 0.055,
curvature = 0.3, arrow = arrow(length = unit(2, "mm"))) +
annotate(geom = "text", x = -0.10, y = 0.09, label = "Pandemia Global", hjust = "left")## LOESS & ggplotly
# Modificar el formato de porcentaje y la etiqueta del texto para ggplotly
homev_vs_Job_growth_II <- homev_vs_Job_growth_II |>
mutate(Home_Value_Index_ch = Home_Value_Index |> scales::percent(accuracy = 0.01)) |>
mutate(Employment_ch = PC_YoY |> scales::percent(accuracy = 0.01)) |>
mutate(label_text = str_glue("Year: {Year},
Home Value Index: {Home_Value_Index_ch},
Employment: {Employment_ch}"))
# Crear un gráfico ggplotly interactivo
p4 <- ggplot(homev_vs_Job_growth_II, aes(Employment, Home_Value_Index)) +
geom_point(aes(text = label_text), size = 2) +
geom_line(data = grid, colour = "blue", size = 1.5) +
ggrepel::geom_text_repel(data = outlier, aes(label = Year)) +
labs(
title = "Regresión LOESS",
y = "Cambio Promedio % Índice de Valor de la Vivienda",
x = "Cambio Promedio % Empleo",
caption = "La regresión LOESS, a veces llamada regresión local, es un método que utiliza el ajuste local para ajustar un modelo de regresión a un conjunto de datos"
) +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent)
# Convertir el gráfico ggplotly a una versión interactiva
p4 |>
ggplotly(tooltip = "text")# Crear un conjunto de datos combinando datos de empleo y datos del índice de valor de la vivienda por año (Plot 5)
homev_vs_Job_growth_III <- Employment_C |>
left_join(avg_zhvi_pc_by_year, by = "Year") |>
select(Year, PC_YoY, "Home Value Index") |>
mutate(Employment = PC_YoY) |>
mutate(Home_Value_Index = `Home Value Index`)
# Añadir nuevas columnas con porcentajes y texto para etiquetas
homev_vs_Job_growth_III <- homev_vs_Job_growth_III |>
mutate(Home_Value_Index_PC = `Home Value Index` |> scales::percent(accuracy = 0.01)) |>
mutate(Employment_PC = PC_YoY |> scales::percent(accuracy = 0.01)) |>
mutate(label_text1 = str_glue("Employment: {Employment_PC}")) |>
mutate(label_text2 = str_glue("Home Value Index: {Home_Value_Index_PC}")) |>
mutate(label_text3 = str_glue("E: {Employment_PC}%")) |>
mutate(label_text4 = str_glue("H: {Home_Value_Index_PC}%"))
# Obtener el rango de años
miny <- homev_vs_Job_growth_III |> pull(Year) |> min()
max_y <- homev_vs_Job_growth_III |> pull(Year) |> max()
# Crear un gráfico de barras apiladas
p5 <- ggplot(homev_vs_Job_growth_III) +
geom_bar(
aes(Year, Employment, text = label_text1),
stat = "identity",
position = "dodge",
fill = "cadetblue1",
color = "black"
) +
geom_bar(
aes(Year, Home_Value_Index, text = label_text2),
stat = "identity",
position = "dodge",
fill = "navy",
color = "black",
alpha = 0.3
) +
scale_y_continuous(labels = scales::percent) +
labs(
title = "Precios de Viviendas vs Empleo",
caption = str_glue("Fuentes de datos: Zillow y Bureau Labor of Statistics \n Marco temporal: {min_y} {max_y}")
) +
geom_label(
aes(Year, Employment, label = label_text3),
hjust = "left",
vjust = "top",
size = 3
) +
geom_label(
aes(Year, Home_Value_Index, label = label_text4),
hjust = "right",
vjust = "bottom",
size = 3
)
# Convertir el gráfico ggplot a una versión interactiva usando plotly
p5 |> ggplotly(tooltip = "text") |>
layout(
title = list(
text = paste(
'Precios de Viviendas vs Empleo',
'<br>',
'<sup>',
'<b>', 'Fuentes de datos:',
'</b>', "(Zillow) & (Bereau Labor of Statistics)",
'</sup>'
)
)
)# Extraer códigos postales y convertirlos a formato entero
CAGR_Data_zip <- CAGR_Data |>
mutate(zip = str_extract(City_zip, pattern = "\\d{5}")) |>
mutate(zip = zip |> as.integer())
# Importar datos demográficos
demographics <- data_import(dataSource = "Demographis")
# Combinar datos de CAGR con datos demográficos utilizando códigos postales
demographics_CAGR <- CAGR_Data_zip |> left_join(demographics, by = "zip")
# Visualizar la estructura de datos
demographics_CAGR |> glimpse()## Rows: 30
## Columns: 16
## $ City_zip <glue> "Detroit_48201", "Detroit_48209", "Det…
## $ Beginning_Value <dbl> 85994.28, 17091.93, 17041.83, 20307.30,…
## $ Ending_Value <dbl> 454612.78, 82906.16, 62032.72, 63603.83…
## $ timeperiod <chr> "2000-2022", "2000-2022", "2000-2022", …
## $ Number_of_Years <dbl> 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,…
## $ CAGR <dbl> 0.07862742, 0.07441617, 0.06048554, 0.0…
## $ zip <int> 48201, 48209, 48210, 48218, 48212, 4803…
## $ success <chr> "true", "true", "true", "true", "true",…
## $ House_Hold_Median_Income <int> 21180, 34104, 33711, 24034, 32439, 5087…
## $ houseHoldMeanIncome <int> 47405, 47947, 43855, 39400, 43899, 5965…
## $ familyMedianIncome <int> 29432, 39947, 39104, 32877, 37337, 5856…
## $ familyMeanIncome <int> 64410, 54050, 49250, 52961, 47899, 6575…
## $ numHouseholds <int> 7741, 9081, 8031, 2894, 11484, 6801, 89…
## $ nonFamilyHouseholdMedianIncome <int> 18331, 19924, 25139, 16829, 23926, 3598…
## $ nonFamilyHouseholdMeanIncome <int> 40064, 30109, 31137, 25584, 32962, 5086…
## $ familyPercentPoverty <dbl> 52.52, 38.98, 40.76, 49.66, 44.16, 25.6…
# Agregar una columna de texto para etiquetas
demographics_CAGR <- demographics_CAGR |>
mutate(label_text = str_glue("Household Median Income: {House_Hold_Median_Income |> scales::dollar()}"))
# Crear un gráfico de barras
p6 <- ggplot(demographics_CAGR, aes(x = reorder(City_zip, -House_Hold_Median_Income))) +
geom_bar(
aes(y = House_Hold_Median_Income, text = label_text),
stat = "identity",
color = "black", fill = "skyblue"
) +
scale_y_continuous(name = "Median Income", labels = scales::dollar) +
labs(x = "ZipCode") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90))
# Convertir el gráfico ggplot a una versión interactiva usando plotly
g_plotly <- p6 |> ggplotly(tooltip = "label_text") |>
layout(
title = list(
text = paste0('<br>',
'Household Median Income',
'</br>',
'<br>',
'<sup>',
'<b>',
'Note:',
'</b>', 'These ZipCodes have the higher CAGR in Metro Detroit',
'</sup>')
)
)
# Ajustar el tamaño del gráfico plotly
g_plotly <- g_plotly %>%
config(displayModeBar = TRUE) %>% # Puedes desactivar la barra de herramientas si lo prefieres
layout(width = 1000, height = 600) # Ajustar el tamaño según tus preferencias
# Mostrar el gráfico plotly
g_plotlyEl Gráfico de Pareto es una herramienta visual poderosa utilizada en gestión y mejora de procesos para identificar y priorizar problemas o causas, centrándose en aquellos que tienen el mayor impacto. Su nombre proviene del principio de Pareto, que sugiere que aproximadamente el 80% de los problemas provienen del 20% de las causas.
# Data Preparation
data <- data.frame(
Category = c("Dose Missed",
"Wrong Time",
"Overdose",
"Wrong Patient",
"Wrong Drug",
"Wrong Calculation",
"Duplicated Dose",
"Under Dose",
"Wrong Rate",
"Technique Error",
"Unauthorized Drug"),
Frequency = c(92, 83, 76, 59, 53, 27, 16, 9, 7, 4, 3)
)
# Ordenar los datos por frecuencia en orden descendente
data <- data |>
arrange(desc(Frequency)) |>
# Calcular la suma acumulativa y el porcentaje acumulativo
mutate(Cumulative = cumsum(Frequency)) |>
mutate(Cumulative_Percent = Cumulative / sum(Frequency) * 100)
# Crear un gráfico de barras y línea (Pareto Chart)
p <- ggplot(data, aes(x = reorder(Category, -Frequency), y = Frequency)) +
geom_bar(
aes(text = paste("Category:", Category, "<br>Frequency:", Frequency)),
stat = "identity",
fill = "blue"
) +
geom_line(
aes(y = Cumulative_Percent,
group = 1,
text = paste("Category:", Category, "<br>Cumulative %:", sprintf("%.2f", Cumulative_Percent))),
colour = "red"
) +
geom_point(
aes(y = Cumulative_Percent,
text = paste("Category:", Category, "<br>Cumulative %:", sprintf("%.2f", Cumulative_Percent))),
colour = "red"
) +
# Agregar una línea de referencia en el 80% para el Pareto
geom_hline(aes(yintercept = 80), linetype = "dashed", color = "green") +
# Agregar eje secundario para el porcentaje acumulativo
scale_y_continuous(sec.axis = sec_axis(~ ., name = "Cumulative %")) +
theme_minimal() +
labs(
x = "Type of Medication Errors",
y = "Frequency #",
title = str_glue("Pareto Chart Types of Medication Errors (n = {data$Frequency |> sum()})")
) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
# Convertir el gráfico ggplot a una versión interactiva usando plotly
p |>
ggplotly(tooltip = "text")LOWESS, que significa “locally weighted scatterplot smoothing” (alisado de gráficos de dispersión ponderado localmente), es un método estadístico utilizado para realizar un suavizado local en datos bidimensionales. LOWESS es un tipo de modelo no paramétrico que se utiliza para explorar la relación entre dos variables, generalmente representadas en un gráfico de dispersión.
El método LOWESS suaviza los datos mediante la aplicación de pesos locales a los puntos de datos en función de su proximidad espacial. Esto significa que el suavizado en cada punto se realiza teniendo en cuenta principalmente los puntos cercanos y asignando pesos más bajos a los puntos más alejados. De esta manera, el modelo se adapta localmente a la variabilidad de los datos y proporciona un suavizado más flexible que algunos métodos globales de suavizado.
Para aplicar el modelo LOWESS, se selecciona un parámetro llamado “ancho de banda” que determina la ventana alrededor de cada punto que se utilizará para calcular el suavizado local. Un ancho de banda más grande incluirá más puntos en el cálculo, lo que dará como resultado un suavizado más suave pero menos sensible a las variaciones locales.
LOWESS es útil en la exploración visual de datos para identificar tendencias o patrones subyacentes, especialmente cuando los datos muestran variabilidad significativa. Este método ha sido utilizado en diversas disciplinas, como estadísticas, econometría y ciencias sociales, para comprender mejor la relación entre variables y detectar tendencias locales en datos ruidosos.
# Carga de bibliotecas ----
library(tidyverse) # Paquete para manipulación y visualización de datos
library(lubridate) # Paquete para manipulación de fechas
library(stringr) # Paquete para manipulación de cadenas de texto
library(fs) # Paquete para operaciones con el sistema de archivos
library(scales) # Paquete para escalas personalizadas en gráficos
# Carga de la biblioteca ggplot2 si no está cargada
library(ggplot2)
# Establecer una semilla para reproducibilidad
set.seed(13)
# Generar datos de ejemplo ----
x <- seq(1, 200, length.out = 200) # Secuencia de valores para x
y <- sin(x/10) + rnorm(200, 0, 0.5) # Función seno con ruido aleatorio
# Aplicar suavizado LOESS ----
smoothed_data <- lowess(x, y)
# Graficar los datos originales y suavizados ----
P1 <- ggplot(mapping = aes(x = x, y = y)) +
geom_point(color = "blue") +
geom_line(aes(y = smoothed_data$y), color = "red") +
ggtitle("LOESS")
P1# Generar tress modelos con diferentes spans
# Entre mas bajo el span mas alta la posibilidad de overfitting
# Cross validation para encontrar el mejor span
model1 <- loess(y ~ x, span = 0.2)
model2 <- loess(y ~ x, span = 0.5)
model3 <- loess(y ~ x, span = 0.8)
# Grafico de comparacion de modelos ----
FP <- ggplot(mapping = aes(x = x, y = y)) +
geom_point(color = "blue") +
geom_line(aes (y = fitted (model1)), color = "red")+
geom_line(aes (y = fitted (model2)), color = "black")+
geom_line(aes (y = fitted (model3)), color = "yellow")+
ggtitle("LOESS")
library(plotly)
FP |> ggplotly()La importancia de gestionar valores atípicos radica en varios aspectos clave. En primer lugar, estos valores pueden distorsionar las medidas estadísticas comunes, como la media y la desviación estándar, generando estimaciones sesgadas y poco representativas de la realidad. Al abordar los valores atípicos, se obtiene una visión más precisa y equilibrada de la distribución de los datos.
Además, los valores atípicos pueden influir significativamente en los modelos predictivos y algoritmos de aprendizaje automático. Si no se gestionan adecuadamente, pueden llevar a la creación de modelos ineficaces o poco precisos. Identificar y tratar estos valores atípicos permite mejorar la robustez y la generalización de los modelos, garantizando un rendimiento más confiable en datos nuevos.
# Data completa
model_data <- read.csv("C:\\Users\\Usuario\\Documents\\R_class\\Analysis_&_Manipulation_De_Datos_En_Espanol\\01_Informacion_Data\\model_data.csv")
dim(model_data)## [1] 3466 6
Eliminar valores atípicos utilizando la desviación estándar (SD) es un enfoque común en estadística para identificar y tratar puntos de datos que se desvían significativamente de la media de un conjunto de datos. El método implica calcular la desviación estándar de los datos y eliminar los valores que están a una cierta distancia (múltiplos de la desviación estándar) de la media.
Aquí hay una descripción básica de cómo funciona este método:
Calcular la Media y la Desviación Estándar:
Se calcula la media (promedio) y la desviación estándar de los datos. Establecer un Umbral:
Se elige un múltiplo de la desviación estándar como umbral. Comúnmente, se utilizan múltiplos como 1, 1.5, 2, o 3, dependiendo de la rigurosidad que se desee aplicar. Identificar y Eliminar Valores Atípicos:
Se identifican los valores que están más allá del umbral establecido en ambos extremos de la distribución (por encima y por debajo de la media). Estos valores se consideran atípicos y se eliminan del conjunto de datos. Revisar y Validar:
Después de eliminar los valores atípicos, es importante revisar el conjunto de datos resultante y considerar si la exclusión de esos valores es justificada. En algunos casos, los valores atípicos pueden contener información importante o representar eventos genuinos. Es importante destacar que este método asume que los datos siguen una distribución normal.
# Calcular la media y la desviación estándar de la columna 'price' en el DataFrame 'model_data'
mean_price <- mean(model_data$price, na.rm = T) # Calcular la media, ignorando los valores NA
sd_price <- sd(model_data$price, na.rm = T) # Calcular la desviación estándar, ignorando los valores NA
# Identificar los valores atípicos basados en la desviación estándar (3 veces la desviación estándar)
outliers <- model_data$price < (mean_price - 3 * sd_price) | model_data$price > (mean_price + 3 * sd_price)
# Crear un nuevo DataFrame 'model1_no_outliers_sd_method' sin los valores atípicos
model1_no_outliers_sd_method <- model_data[!outliers, ]
# Mostrar información sobre el nuevo DataFrame utilizando la función 'glimpse()'
model1_no_outliers_sd_method |> glimpse()## Rows: 3,460
## Columns: 6
## $ year <int> 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 20…
## $ zipCode <int> 48221, 48221, 48221, 48221, 48221, 48221, 48221, 48221, …
## $ price <int> 1000, 975, 1450, 1050, 1250, 1100, 1500, 1575, 1100, 120…
## $ bathrooms <dbl> 1.0, 1.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.5, 1.0, 1.0, 1.5, 2…
## $ bedrooms <int> 2, 2, 5, 2, 2, 2, 2, 3, 2, 2, 4, 3, 2, 1, 3, 3, 2, 3, 3,…
## $ squareFootage <int> 1295, 1000, 1188, 2262, 1000, 1148, 879, 1400, 1143, 105…
Eliminar valores atípicos con el método IQR (rango intercuartílico) es otra técnica común en estadística. El rango intercuartílico es la diferencia entre el tercer cuartil (Q3) y el primer cuartil (Q1) de un conjunto de datos. Los valores atípicos se identifican y eliminan si están por debajo de Q1 - 1.5 * IQR o por encima de Q3 + 1.5 * IQR. Aquí hay un ejemplo de cómo implementar esto en R:
# Calcular el primer cuartil (Q1)
Q1 <- quantile(model_data$price, 0.25)
# Calcular el tercer cuartil (Q3)
Q3 <- quantile(model_data$price, 0.75)
# Calcular el rango intercuartílico (IQR)
IQR <- Q3 - Q1
# Identificar los valores atípicos utilizando el método IQR
outliers <- model_data$price < (Q1 - 1.5 * IQR) | model_data$price > (Q3 + 1.5 * IQR)
# Crear un nuevo DataFrame sin valores atípicos
model2_no_outliers_IQR_method <- model_data[!outliers, ]
# Mostrar información sobre el nuevo DataFrame sin valores atípicos
glimpse(model2_no_outliers_IQR_method)## Rows: 3,310
## Columns: 6
## $ year <int> 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 20…
## $ zipCode <int> 48221, 48221, 48221, 48221, 48221, 48221, 48221, 48221, …
## $ price <int> 1000, 975, 1450, 1050, 1250, 1100, 1500, 1575, 1100, 120…
## $ bathrooms <dbl> 1.0, 1.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.5, 1.0, 1.0, 1.5, 2…
## $ bedrooms <int> 2, 2, 5, 2, 2, 2, 2, 3, 2, 2, 4, 3, 2, 1, 3, 3, 2, 3, 3,…
## $ squareFootage <int> 1295, 1000, 1188, 2262, 1000, 1148, 879, 1400, 1143, 105…
El Método de Desviación Absoluta de la Mediana (Median Absolute Deviation, MAD) es un enfoque robusto utilizado para identificar valores atípicos en un conjunto de datos. A diferencia de otros métodos que dependen de la media y la desviación estándar, el MAD utiliza la mediana como medida central y evalúa la dispersión de los datos en términos de desviaciones absolutas respecto a la mediana.
# Calcular la Desviación Absoluta de la Mediana (MAD)
MAD <- mad(model_data$price, constant = 1)
# Identificar valores atípicos utilizando el método robusto MAD
outliers <- abs(model_data$price - median(model_data$price)) / MAD > 2
# Crear un nuevo DataFrame sin valores atípicos utilizando el método robusto
model3_no_outliers_robust_method <- model_data[!outliers, ]
# Mostrar información sobre el nuevo DataFrame sin valores atípicos
model3_no_outliers_robust_method |> glimpse()## Rows: 2,811
## Columns: 6
## $ year <int> 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 20…
## $ zipCode <int> 48221, 48221, 48221, 48221, 48221, 48221, 48221, 48221, …
## $ price <int> 1000, 975, 1450, 1050, 1250, 1100, 1500, 1575, 1100, 120…
## $ bathrooms <dbl> 1.0, 1.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.5, 1.0, 1.0, 1.5, 2…
## $ bedrooms <int> 2, 2, 5, 2, 2, 2, 2, 3, 2, 2, 4, 3, 2, 1, 3, 3, 2, 3, 3,…
## $ squareFootage <int> 1295, 1000, 1188, 2262, 1000, 1148, 879, 1400, 1143, 105…
La comprobación de linealidad se refiere a la evaluación de la relación entre variables en un modelo estadístico o matemático para determinar si esta relación es lineal. En el contexto de análisis de regresión, la linealidad es una suposición fundamental. La comprobación de linealidad implica asegurarse de que la relación entre la variable dependiente y las variables independientes pueda ser bien aproximada mediante una línea recta.
# Lista de variables a incluir en los gráficos de dispersión
variables <- list("bathrooms", "bedrooms", "squareFootage", "zipCode")
# Función para crear gráficos de dispersión
create_scatter_plot_fun <- function(variables) {
ggplot(model1_no_outliers_sd_method, aes(!!sym(variables), price)) +
geom_point() + # Añadir puntos al gráfico
labs(title = paste("Gráfico de dispersión de precio vs", variables),
x = variables,
y = "Precio")
}
# Crear una lista de gráficos utilizando la función map
plots <- map(variables, create_scatter_plot_fun)
# Organizar los gráficos en una cuadrícula
library(gridExtra)## Warning: package 'gridExtra' was built under R version 4.2.3
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
# Gráficos de Residuos
Los gráficos de residuos son herramientas visuales utilizadas en el análisis de regresión para evaluar la calidad del ajuste de un modelo a los datos observados. Los residuos son las diferencias entre los valores observados y los valores predichos por el modelo. Al examinar los patrones y distribuciones de estos residuos, se pueden identificar posibles violaciones de las suposiciones del modelo de regresión.
# Lista de conjuntos de datos que contienen modelos sin valores atípicos
data_sets <- list(
"model1_no_outliers_sd_method" = model1_no_outliers_sd_method,
"model2_no_outliers_IQR_method" = model2_no_outliers_IQR_method,
"model3_no_outliers_robust_method" = model3_no_outliers_robust_method
)
# Fórmula del modelo de regresión lineal
formula <- price ~ bathrooms + bedrooms + squareFootage + zipCode
# Ajustar modelos de regresión lineal a cada conjunto de datos
models <- map(data_sets, ~ lm(formula, data = .x))
# Función para crear gráficos de residuos vs valores ajustados
create_residuals_plot_fun <- function(model, model_name) {
ggplot() +
geom_point(aes(x = model$fitted.values, y = model$residuals)) +
labs(
title = paste("Residuos vs Valores Ajustados para", model_name),
x = "Valores Ajustados",
y = "Residuos"
)
}
# Crear gráficos de residuos vs valores ajustados para cada modelo
plots <- map2(models, names(models), create_residuals_plot_fun)
# Organizar los gráficos en una cuadrícula de 2 columnas
grid.arrange(plots[[1]], plots[[2]], plots[[3]], ncol = 2)
## Normal Q - Q
Un Q-Q plot compara la distribución de los residuos con una distribución teórica (generalmente la distribución normal). Si los puntos del Q-Q plot siguen aproximadamente una línea diagonal, sugiere que los residuos se distribuyen de manera normal.
## Warning: package 'ggpubr' was built under R version 4.2.3
## Warning: package 'cowplot' was built under R version 4.2.3
##
## Attaching package: 'cowplot'
## The following object is masked from 'package:ggpubr':
##
## get_legend
## The following object is masked from 'package:lubridate':
##
## stamp
models <- list(
"model1_no_outliers_sd_method" = lm(price ~ bathrooms + bedrooms + squareFootage + zipCode, data = model1_no_outliers_sd_method),
"model2_no_outliers_IQR_method" = lm(price ~ bathrooms + bedrooms + squareFootage + zipCode, data = model2_no_outliers_IQR_method),
"model3_no_outliers_robust_method" = lm(price ~ bathrooms + bedrooms + squareFootage + zipCode, data = model3_no_outliers_robust_method)
)
# Función para crear gráficos Q-Q plot para los residuos de un modelo
create_qq_plot <- function(model_name, model) {
residuals <- model$residuals
qqplot <- ggqqplot(residuals) +
ggtitle(paste("Gráfico Q-Q para", model_name))
return(qqplot)
}
# Crear gráficos Q-Q plot para cada modelo
plots <- map2(names(models), models, create_qq_plot)
# Organizar los gráficos en una cuadrícula de 2 columnas usando plot_grid
combined_plot <- plot_grid(plotlist = plots, ncol = 2)
print(combined_plot)El coeficiente de correlación es una medida estadística que cuantifica la relación lineal entre dos variables. En otras palabras, el coeficiente de correlación indica en qué medida las variaciones en una variable están asociadas con las variaciones en otra variable. Esta medida se utiliza comúnmente para evaluar la fuerza y dirección de la relación entre dos variables continuas.
Existen diferentes tipos de coeficientes de correlación, pero uno de los más comunes es el coeficiente de correlación de Pearson. El coeficiente de correlación de Pearson, denotado como “r”, tiene un rango de -1 a 1, donde:
1: Indica una correlación perfecta positiva. Esto significa que a medida que una variable aumenta, la otra variable también aumenta en una relación lineal perfecta.
0: Indica ausencia de correlación lineal. No hay relación lineal entre las dos variables.
-1: Indica una correlación perfecta negativa. Esto significa que a medida que una variable aumenta, la otra variable disminuye en una relación lineal perfecta.
# Calcular el coeficiente de correlación entre price y bathrooms
cor_bathrooms <- cor(model1_no_outliers_sd_method$price, model1_no_outliers_sd_method$bathrooms, use = "complete.obs")
print(paste("Coeficiente de correlación entre price y bathrooms:", cor_bathrooms))## [1] "Coeficiente de correlación entre price y bathrooms: 0.611636865410224"
# Calcular el coeficiente de correlación entre price y bedrooms
cor_bedrooms <- cor(model1_no_outliers_sd_method$price, model1_no_outliers_sd_method$bedrooms, use = "complete.obs")
print(paste("Coeficiente de correlación entre price y bedrooms:", cor_bedrooms))## [1] "Coeficiente de correlación entre price y bedrooms: 0.269333937837847"
# Calcular el coeficiente de correlación entre price y squareFootage
cor_squareFootage <- cor(model1_no_outliers_sd_method$price, model1_no_outliers_sd_method$squareFootage, use = "complete.obs")
print(paste("Coeficiente de correlación entre price y squareFootage:", cor_squareFootage))## [1] "Coeficiente de correlación entre price y squareFootage: 0.09230062429832"
Las transformaciones de datos, como tomar el logaritmo, la raíz cuadrada o elevar al cuadrado, son técnicas utilizadas en el análisis de datos por diversas razones. El propósito principal de estas transformaciones es modificar la distribución de los datos o la relación entre las variables para satisfacer las suposiciones de los métodos estadísticos o mejorar la interpretabilidad de los resultados. Aquí hay algunas razones comunes para realizar transformaciones:
En el análisis de regresión, se asume que la varianza de los errores es constante en todos los niveles de las variables predictoras. Si hay una relación no constante entre la varianza y las variables predictoras, las transformaciones como la raíz cuadrada o el logaritmo pueden ayudar a estabilizar la varianza.
En algunos casos, la relación entre las variables puede ser no lineal, pero los modelos estadísticos asumen una relación lineal. Tomar el logaritmo o la raíz cuadrada de una variable puede ayudar a linealizar la relación, permitiendo así que se apliquen modelos lineales.
Si los datos tienen una distribución sesgada hacia la derecha, donde hay valores atípicos que se encuentran en el extremo superior, tomar el logaritmo puede reducir el sesgo y hacer que la distribución sea más simétrica.
Elevar al cuadrado o tomar la raíz cuadrada de una variable puede cambiar la escala de los datos, lo que puede ser útil para resaltar patrones o reducir la importancia de valores extremos.
En algunos métodos estadísticos, como las pruebas de hipótesis paramétricas, se asume la normalidad de los datos. Transformaciones como el logaritmo pueden ayudar a que los datos se aproximen más a una distribución normal.
En ocasiones, realizar transformaciones puede hacer que los resultados sean más interpretables o más fácilmente comparables. Es importante señalar que la elección de una transformación específica depende de la naturaleza de los datos y de los objetivos del análisis. Además, se debe tener precaución al interpretar resultados transformados, ya que pueden afectar la interpretación de los coeficientes o las métricas de evaluación del modelo. La selección de una transformación adecuada a menudo implica explorar y comprender la naturaleza de los datos.
# Crear un nuevo DataFrame con la transformación logarítmica de squareFootage
m1_log <- model1_no_outliers_sd_method |>
mutate(squareFootage = log(squareFootage))
# Crear un nuevo DataFrame con la transformación de raíz cuadrada de squareFootage
m1_sqrt <- model1_no_outliers_sd_method |>
mutate(squareFootage = sqrt(squareFootage))
# Crear un nuevo DataFrame con la transformación cuadrática de squareFootage
m1_sq2 <- model1_no_outliers_sd_method |>
mutate(squareFootage = (squareFootage)^2)
# Lista de modelos de regresión lineal con diferentes transformaciones de squareFootage
models <- list(
"model_no_outliers_sd_method" = lm(price ~ bathrooms + bedrooms + squareFootage + zipCode, data = model1_no_outliers_sd_method),
"ml_log" = lm(price ~ bathrooms + bedrooms + squareFootage + zipCode, data = m1_log),
"m1_sqrt"= lm(price ~ bathrooms + bedrooms + squareFootage + zipCode, data = m1_sqrt),
"m1_sq2" = lm(price ~ bathrooms + bedrooms + squareFootage + zipCode, data = m1_sq2)
)
# Función para crear gráficos de residuos vs valores ajustados
create_residuals_plot <- function(model_name, model) {
ggplot() +
geom_point(aes(x = model$fitted.values, y = model$residuals)) +
labs(
title = paste("Residuos vs Valores Ajustados para", model_name),
x = "Valores Ajustados",
y = "Residuos"
)
}
# Crear gráficos de residuos vs valores ajustados para cada modelo
plots <- map2(names(models), models, create_residuals_plot)
# Organizar los gráficos en una cuadrícula de 2 columnas
grid.arrange(plots[[1]], plots[[2]], plots[[3]], plots[[4]], ncol = 2)